package com.example.login.service.impl;

import com.example.login.dto.LoginRequest;
import com.example.login.dto.LoginResponse;
import com.example.login.dto.RegisterRequest;
import com.example.login.dto.SmsLoginRequest;
import com.example.login.model.User;
import com.example.login.repository.UserRepository;
import com.example.login.service.UserService;
import com.example.login.util.JwtTokenUtil;
import com.example.login.util.RedisUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.Random;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Value("${sms.expiration}")
    private long smsExpiration;

    @Value("${sms.length}")
    private int smsLength;

    @Override
    public User getUserByUsername(String username) {
        return userRepository.findByUsername(username).orElse(null);
    }

    @Override
    public User getUserByPhone(String phone) {
        return userRepository.findByPhone(phone).orElse(null);
    }

    @Override
    public User register(RegisterRequest registerRequest) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查手机号是否已存在
        if (userRepository.existsByPhone(registerRequest.getPhone())) {
            throw new RuntimeException("手机号已被注册");
        }
        
        // 创建新用户
        User user = new User();
        BeanUtils.copyProperties(registerRequest, user);
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        
        // 保存用户
        return userRepository.save(user);
    }

    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        // 根据用户名查询用户
        User user = getUserByUsername(loginRequest.getUsername());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        // 生成token
        String token = jwtTokenUtil.generateToken(user.getUsername());
        
        // 构建登录响应
        return buildLoginResponse(user, token);
    }

    @Override
    public LoginResponse loginBySms(SmsLoginRequest smsLoginRequest) {
        String phone = smsLoginRequest.getPhone();
        String code = smsLoginRequest.getCode();
        
        // 验证短信验证码
        if (!verifySmsCode(phone, code)) {
            throw new RuntimeException("验证码错误或已过期");
        }
        
        // 查询用户
        User user = getUserByPhone(phone);
        if (user == null) {
            throw new RuntimeException("用户不存在，请先注册");
        }
        
        // 生成token
        String token = jwtTokenUtil.generateToken(user.getUsername());
        
        // 删除验证码
        redisUtil.deleteSmsCode(phone);
        
        // 构建登录响应
        return buildLoginResponse(user, token);
    }

    @Override
    public boolean sendSmsCode(String phone) {
        // 生成随机验证码
        String code = generateSmsCode(smsLength);
        
        // 存储验证码到Redis
        redisUtil.setSmsCode(phone, code, smsExpiration);
        
        // 模拟发送短信
        System.out.println("向手机号" + phone + "发送验证码：" + code);
        
        return true;
    }

    @Override
    public boolean verifySmsCode(String phone, String code) {
        return redisUtil.validateSmsCode(phone, code);
    }

    /**
     * 构建登录响应
     */
    private LoginResponse buildLoginResponse(User user, String token) {
        return LoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .phone(user.getPhone())
                .token(token)
                .tokenHead(tokenHead)
                .build();
    }

    /**
     * 生成随机短信验证码
     */
    private String generateSmsCode(int length) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }
}